//游戏步骤（包括构造，对整个战役参数的修改，显示动画效果，动画效果时间）

var ProcessData = function(tick, type, troopid, tileIndex, param, duration){
	this.tick = tick;
	this.type = type;
	this.troopid = troopid;
	this.tileIndex = tileIndex;
	this.param = param;
	this.duration = duration;
};

//获取某地块情报
var processGetInfo = {
	id : 1,

	CreateParam : function(range){
		return { range : range };
	},

	Modify : function(data){
		if (data.param.range > 0){
			ForceInfo.RefreshTileAndNeighbor(
				forceInfo[campaign.troop[data.troopid].force],
				data.tileIndex,
				campaign.zone,
				tileEngine);
		}
		else{
			ForceInfo.RefreshTile(
				forceInfo[campaign.troop[data.troopid].force],
				data.tileIndex,
				campaign.zone);
		}
	},

	duration : 0.02,

	Play : function(data){
		if (campaign.troop[data.troopid].force == showingForce){
			//刷新战争迷雾/作战情报
			if (data.param.range <= 0){
				warMist.RefreshTileVisible(data.tileIndex);
				warInfo.RefreshTileInfo(data.tileIndex);
			}else{
				warMist.RefreshTileAndNeighbourVisible(data.tileIndex);
				warInfo.RefreshTileAndNeighbourInfo(data.tileIndex);
			}
		}
		//刷新单位可视性
		warTroop.RefreshTroopVisible();
	}
};

//移动
var processMove = {
	id : 2,
	
	CreateParam : function(ori_orientation, tgt_orientation){
		return { ori_orientation:ori_orientation, tgt_orientation:tgt_orientation };
	},
	
	Modify : function(data){
		campaign.troop[data.troopid].tileIndex = data.tileIndex;
		campaign.troop[data.troopid].orientation = data.param.tgt_orientation;
	},
	
	duration : 0.3,
	
	Play : function(data){
		var sprite = warTroop.troopSprites[data.troopid];
		var holder = warTroop.troopHolders[data.troopid];
		
		orientationEngine.TurnOrientation(sprite, data.param.ori_orientation, data.param.tgt_orientation);
		var coord = tileEngine.IndexToCoord(data.tileIndex);
		holder.runAction(cc.moveTo(0.25, cc.p(coord.x,coord.y)));
		
		warTroop.sortTileIndex = data.tileIndex;
		
		//no bad result of layer-destroy
		setTimeout(warTroop.SortTroop, 0.29 * 1000);
	}
};

//侦搜(空袭)
var processRecon = {
	id : 3,

	CreateParam : function(tgt_troopid, damage, strength){
		return {
			tgt_troopid:tgt_troopid,
			damage:damage,
			strength:strength
		};
	},

	Modify : function(data){
		if (data.param.tgt_troopid >= 0){
			campaign.troop[data.troopid].strength -= data.param.damage.damageAttack;
			campaign.troop[data.param.tgt_troopid].strength -= data.param.damage.damageDefend;
		}
	},

	duration : 2.1,

	Play : function(data){
		var spriteAttack = warTroop.troopSprites[data.troopid];
		var holderAttack = warTroop.troopHolders[data.troopid];

		var placeCoord = {x:warTroop.troopHolders[data.troopid].x, y:warTroop.troopHolders[data.troopid].y};
		var forceid = campaign.troop[data.troopid].force;
		var startCoord = {x:terrain.forceflagSprite[forceid].x, y:terrain.forceflagSprite[forceid].y};
		var centerCoord = tileEngine.IndexToCoord(data.tileIndex);
		var route = this._GetFlyRoute(startCoord, centerCoord, tileEngine.tileWidth);

		var route1 = [cc.p(route[0].x, route[0].y), cc.p(route[1].x, route[1].y), cc.p(route[2].x, route[2].y), cc.p(route[3].x, route[3].y)];
		var route2 = [cc.p(route[4].x, route[4].y), cc.p(route[5].x, route[5].y), cc.p(route[6].x, route[6].y)];

		holderAttack.setPosition(startCoord.x, startCoord.y);
		holderAttack.runAction(cc.sequence(
			cc.place(startCoord.x,startCoord.y),
			cc.show(),
			cc.bezierTo(1, route1),
			cc.bezierTo(1, route2),
			cc.hide(),
			cc.place(placeCoord.x,placeCoord.y)
		));

		spriteAttack.attr({scale:1, rotation:TwoPointHeading(route[0], route[1])});
		spriteAttack.runAction(cc.sequence(
			cc.delayTime(0.5),
			cc.rotateTo(0.5, TwoPointHeading(route[2], route[4])),
			cc.rotateTo(0.5, TwoPointHeading(route[5], route[6]))
		));

		if (data.param.tgt_troopid < 0)
			return;

		var spriteDefend = warTroop.troopSprites[data.param.tgt_troopid];
		var holderDefend = warTroop.troopHolders[data.param.tgt_troopid];

		var angle = - TwoPointHeading(centerCoord, {x:holderDefend.x, y:holderDefend.y} ) / 180 * Math.PI;
		var len = 0.6 * tileEngine.tileWidth;
		var vector = {x:0.5 * len * Math.cos(angle), y:0.5 * len * Math.sin(angle)};

		//被攻击者震动
		spriteDefend.runAction(cc.sequence(cc.delayTime(1), cc.shake(0.2, 0.2 * len)));

		//爆炸火团出现
		spriteExplosion.setPosition(holderDefend.x - vector.x, holderDefend.y - vector.y);
		spriteExplosion.runAction(cc.sequence(cc.delayTime(1), cc.show(), cc.delayTime(0.2), cc.hide()));

		//伤害数值出现
		var labelInOut = cc.sequence(cc.delayTime(1), cc.show(), cc.delayTime(0.45), cc.hide());
		var labelUp = cc.sequence(cc.delayTime(1), cc.moveBy(0.2, 0, len));

		if (data.param.damage.damageAttack > 0){
			labelDamageAttack.setString("-" + FormatNumber(data.param.damage.damageAttack, 3));
			labelDamageAttack.setPosition(route[3].x, route[3].y);
			labelDamageAttack.runAction(labelInOut);
			labelDamageAttack.runAction(labelUp);

			//刷新血条
			troopInfo.RefreshTroopInfo(data.troopid,
				data.param.strength.strengthAttack / campaign_ori.troop[data.troopid].strength);
		}

		if (data.param.damage.damageDefend > 0){
			labelDamageDefend.setPosition(holderDefend.x, holderDefend.y);
			labelDamageDefend.setString("-" + FormatNumber(data.param.damage.damageDefend, 3));
			labelDamageDefend.runAction(labelInOut.clone());
			labelDamageDefend.runAction(labelUp.clone());

			//刷新血条
			troopInfo.RefreshTroopInfo(data.param.tgt_troopid,
				data.param.strength.strengthDefend / campaign_ori.troop[data.param.tgt_troopid].strength);
		}
	},

	_GetFlyRoute : function(startCoord, centerCoord, radius){
		var startDegree = TwoPointHeading(startCoord, centerCoord);

		var routePoints = [ startCoord ];
		for (var idx = -2; idx < 3; idx++){
			var rad = -(startDegree - 45 * idx) / 180 * Math.PI
			routePoints[idx + 3] = {
				x : centerCoord.x + radius * Math.cos(rad),
				y : centerCoord.y + radius * Math.sin(rad)};
		}
		routePoints[6] = {x : startCoord.x, y : startCoord.y};
		return routePoints;
	}
};

//攻击
var labelDamageAttack = null;
var labelDamageDefend = null;
var spriteExplosion = null;

var processAttack = {
	id : 4,
	
	CreateParam : function(tgt_troopid, damage, strength, ori_orientation, tgt_orientation){
		return {
			tgt_troopid:tgt_troopid,
			damage:damage,
			strength:strength,
			ori_orientation:ori_orientation,
			tgt_orientation:tgt_orientation
		};
	},
	
	Modify : function(data){
		campaign.troop[data.troopid].strength -= data.param.damage.damageAttack;
		campaign.troop[data.param.tgt_troopid].strength -= data.param.damage.damageDefend;
		campaign.troop[data.troopid].orientation = data.param.tgt_orientation;
	},
	
	duration : 0.8,
	
	Play : function(data){
		var spriteAttack = warTroop.troopSprites[data.troopid];
		var holderAttack = warTroop.troopHolders[data.troopid];
		
		var spriteDefend = warTroop.troopSprites[data.param.tgt_troopid];
		var holderDefend = warTroop.troopHolders[data.param.tgt_troopid];
		
		//旋转角度
		orientationEngine.TurnOrientation(spriteAttack, data.param.ori_orientation, data.param.tgt_orientation);
		
		//攻击者移动
		var oriCoord = {x:holderAttack.x, y:holderAttack.y};
		var tgtCoord = {x:holderDefend.x, y:holderDefend.y};
		var angle = - TwoPointHeading(oriCoord, tgtCoord) / 180 * Math.PI;
		var len = 0.6 * tileEngine.tileWidth;
		var vector = {x:0.5 * len * Math.cos(angle), y:0.5 * len * Math.sin(angle)};
		spriteAttack.runAction(cc.sequence(cc.moveBy(0.1, vector.x, vector.y), cc.moveBy(0.1, -vector.x, -vector.y)));

		//被攻击者震动
		spriteDefend.runAction(cc.shake(0.2, 0.2 * len));

		//爆炸火团出现
		spriteExplosion.setPosition(tgtCoord.x - vector.x, tgtCoord.y - vector.y);
		spriteExplosion.runAction(cc.sequence(cc.show(),cc.delayTime(0.2),cc.hide()));
		
		//伤害数值出现
		var labelInOut = cc.sequence(cc.show(), cc.delayTime(0.45), cc.hide());
		var labelUp = cc.moveBy(0.2, 0, len);
		
		if (data.param.damage.damageAttack > 0){
			labelDamageAttack.setPosition(oriCoord.x, oriCoord.y);
			labelDamageAttack.setString("-" + FormatNumber(data.param.damage.damageAttack, 3));
			labelDamageAttack.runAction(labelInOut);
			labelDamageAttack.runAction(labelUp);

			//刷新血条
			troopInfo.RefreshTroopInfo(data.troopid,
				data.param.strength.strengthAttack / campaign_ori.troop[data.troopid].strength);
		}
		
		if (data.param.damage.damageDefend > 0){
			labelDamageDefend.setPosition(tgtCoord.x, tgtCoord.y);
			labelDamageDefend.setString("-" + FormatNumber(data.param.damage.damageDefend, 3));
			labelDamageDefend.runAction(labelInOut.clone());
			labelDamageDefend.runAction(labelUp.clone());

			//刷新血条
			troopInfo.RefreshTroopInfo(data.param.tgt_troopid,
				data.param.strength.strengthDefend / campaign_ori.troop[data.param.tgt_troopid].strength);
		}
	}
};

//修改地块通行指数
var spritePassUp = null;
var spritePassDown = null;
var processPassIndex = {
	id : 5,
	
	CreateParam : function(passDiv){
		return { passDiv:passDiv };
	},

	Modify : function(data){
		campaign.zone.pass_index[data.tileIndex] += data.param.passDiv;
	},

	duration : 0.3,

	Play : function(data){
		if (warMist.mistSprites[data.tileIndex].isVisible())
			return;
		
		var tgtCoord = tileEngine.IndexToCoord(data.tileIndex);

		var len = 0.6 * tileEngine.tileWidth;

		var labelInOut = cc.sequence(cc.show(), cc.delayTime(0.25), cc.hide());
		var labelUp = cc.moveBy(0.15, 0, 0.3 * len);
		var labelDown = cc.moveBy(0.15, 0, -0.3 * len);
		
		if (data.param.passDiv == 0){
			return;
		}else if (data.param.passDiv > 0){
			spritePassDown.setPosition(tgtCoord.x, tgtCoord.y + len);
			spritePassDown.runAction(labelInOut);
			spritePassDown.runAction(labelDown);
		}else{
			spritePassUp.setPosition(tgtCoord.x, tgtCoord.y + 0.7 * len);
			spritePassUp.runAction(labelInOut);
			spritePassUp.runAction(labelUp);
		}
	}
};

//修改地块防御指数
var spriteDefendUp = null;
var spriteDefendDown = null;
var processDefendIndex = {
	id : 6,
	
	CreateParam : function(defendDiv){
		return { defendDiv:defendDiv };
	},

	Modify : function(data){
		campaign.zone.defend_index[data.tileIndex] += data.param.defendDiv;
	},

	duration : 0.3,

	Play : function(data){
		if (warMist.mistSprites[data.tileIndex].isVisible())
			return;
		
		var tgtCoord = tileEngine.IndexToCoord(data.tileIndex);
		
		var len = 0.6 * tileEngine.tileWidth;

		var labelInOut = cc.sequence(cc.show(), cc.delayTime(0.25), cc.hide());
		var labelUp = cc.moveBy(0.15, 0, 0.3 * len);
		var labelDown = cc.moveBy(0.15, 0, -0.3 * len);
		
		if (data.param.defendDiv == 0){
			return;
		}else if (data.param.defendDiv > 0){
			spriteDefendUp.setPosition(tgtCoord.x, tgtCoord.y + 0.7 * len);
			spriteDefendUp.runAction(labelInOut);
			spriteDefendUp.runAction(labelUp);
		}else{
			spriteDefendDown.setPosition(tgtCoord.x, tgtCoord.y + len);
			spriteDefendDown.runAction(labelInOut);
			spriteDefendDown.runAction(labelDown);
		}
	}
};

//修改部队状态
var processTroopStatus = {
	id : 7,

	CreateParam : function(tieTimer, morale){
		return { tieTimer : tieTimer, morale : morale };
	},

	Modify : function(data){
		if (data.param.tieTimer >= 0){
			campaign.troop[data.troopid].tieTimer = data.param.tieTimer;
		}
		if (data.param.morale >= 0){
			campaign.troop[data.troopid].morale = data.param.morale;
		}
	},

	duration : 0.05,

	Play : function(data){
		if (data.param.tieTimer >= 0){
			SetTieEffect(warTroop.troopSprites[data.troopid], data.param.tieTimer);
		}
		if (data.param.morale >= 0){
			troopInfo.RefreshTroopMorale(data.troopid, data.param.morale);
		}
	}
};

//部队消失(被消灭)
var spriteMiss = null;
var processMiss = {
	id : 8,
	
	CreateParam : function(){
		return { };
	},

	Modify : function(data){
	},

	duration : 0.5,

	Play : function(data){
		var tgtCoord = tileEngine.IndexToCoord(data.tileIndex);
		spriteMiss.setPosition(tgtCoord.x, tgtCoord.y);
		spriteMiss.runAction(cc.sequence(cc.show(), cc.delayTime(0.5), cc.hide()));
		
		warTroop.RemoveTroop(data.troopid);
	}
};

//部队投降
var spriteSurrend = null;
var processSurrend = {
	id : 9,

	CreateParam : function(){
		return { };
	},

	Modify : function(data){
		campaign.troop[data.troopid].strength = 0;
	},

	duration : 0.5,

	Play : function(data){
		var tgtCoord = tileEngine.IndexToCoord(data.tileIndex);
		spriteSurrend.setPosition(tgtCoord.x, tgtCoord.y);
		spriteSurrend.runAction(cc.sequence(cc.show(), cc.rotateTo(0.15, -22), cc.rotateTo(0.15, 22), cc.delayTime(0.2), cc.hide()));

		warTroop.RemoveTroop(data.troopid);
	}
};

//步骤类指针
var processCursor = [];
/* 1 */processCursor[processGetInfo.id] = processGetInfo;
/* 2 */processCursor[processMove.id] = processMove;
/* 3 */processCursor[processRecon.id] = processRecon;
/* 4 */processCursor[processAttack.id] = processAttack;
/* 5 */processCursor[processPassIndex.id] = processPassIndex;
/* 6 */processCursor[processDefendIndex.id] = processDefendIndex;
/* 7 */processCursor[processTroopStatus.id] = processTroopStatus;
/* 8 */processCursor[processMiss.id] = processMiss;
/* 9 */processCursor[processSurrend.id] = processSurrend;

//各步骤所需初始化
var ProcessInitialize = function(){
	labelDamageAttack = cc.LabelTTF.create("", "simhei", 40);
	labelDamageAttack.attr({x: -5000, y: -5000, visible:false});
	labelDamageAttack.setColor(cc.color(255,0,0));
	mainMap.node.addChild(labelDamageAttack, 110);

	labelDamageDefend = cc.LabelTTF.create("", "simhei", 40);
	labelDamageDefend.attr({x: -5000, y: -5000, visible:false});
	labelDamageDefend.setColor(cc.color(255,0,0));
	mainMap.node.addChild(labelDamageDefend, 110);

	spriteExplosion = new cc.Sprite(resource.underAttack_png);
	spriteExplosion.attr({x: -5000, y: -5000, visible:false});
	mainMap.node.addChild(spriteExplosion, 110);

	spriteDefendUp = new cc.Sprite(resource.defendUp_png);
	spriteDefendUp.attr({x: -5000, y: -5000, visible:false});
	mainMap.node.addChild(spriteDefendUp, 110);

	spriteDefendDown = new cc.Sprite(resource.defendDown_png);
	spriteDefendDown.attr({x: -5000, y: -5000, visible:false});
	mainMap.node.addChild(spriteDefendDown, 110);

	spritePassUp = new cc.Sprite(resource.passUp_png);
	spritePassUp.attr({x: -5000, y: -5000, visible:false});
	mainMap.node.addChild(spritePassUp, 110);

	spritePassDown = new cc.Sprite(resource.passDown_png);
	spritePassDown.attr({x: -5000, y: -5000, visible:false});
	mainMap.node.addChild(spritePassDown, 110);

	spriteMiss = new cc.Sprite(resource.miss_png);
	spriteMiss.attr({x: -5000, y: -5000, visible:false});
	mainMap.node.addChild(spriteMiss, 110);
	
	spriteSurrend = new cc.Sprite(resource.flag_png);
	spriteSurrend.attr({x: -5000, y:-5000, rotation:22, visible:false});
	mainMap.node.addChild(spriteSurrend, 110);
};